package com.rymcu.forest.auth;

import com.rymcu.forest.dto.TokenUser;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;

/**
 * JWT Authentication Token for Spring Security 6
 *
 * @author ronger
 */
public class JwtAuthenticationToken extends AbstractAuthenticationToken {

    private final String token;
    private final TokenUser tokenUser;
    private final UserDetails userDetails;

    public JwtAuthenticationToken(String token) {
        super(Collections.emptyList());
        this.token = token;
        this.tokenUser = null;
        this.userDetails = null;
        setAuthenticated(false);
    }

    public JwtAuthenticationToken(String token, TokenUser tokenUser, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.token = token;
        this.tokenUser = tokenUser;
        this.userDetails = createUserDetails(tokenUser, authorities);
        setAuthenticated(true);
    }

    private UserDetails createUserDetails(TokenUser tokenUser, Collection<? extends GrantedAuthority> authorities) {
        return new UserDetails() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return authorities;
            }

            @Override
            public String getPassword() {
                return null;
            }

            @Override
            public String getUsername() {
                return tokenUser.getAccount();
            }

            @Override
            public boolean isAccountNonExpired() {
                return true;
            }

            @Override
            public boolean isAccountNonLocked() {
                return true;
            }

            @Override
            public boolean isCredentialsNonExpired() {
                return true;
            }

            @Override
            public boolean isEnabled() {
                return true;
            }
        };
    }

    @Override
    public Object getCredentials() {
        return token;
    }

    @Override
    public Object getPrincipal() {
        return userDetails != null ? userDetails : token;
    }

    public String getToken() {
        return token;
    }

    public TokenUser getTokenUser() {
        return tokenUser;
    }

    public UserDetails getUserDetails() {
        return userDetails;
    }

    public Long getUserId() {
        return tokenUser != null ? tokenUser.getIdUser() : null;
    }

    public String getAccount() {
        return tokenUser != null ? tokenUser.getAccount() : null;
    }
}